﻿@page "/history/{Id:guid?}"
@using Gurux.DLMS.AMI.Shared
@using Gurux.DLMS.AMI.Shared.DIs

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs
@using Gurux.DLMS.AMI.Shared.Rest
@using Microsoft.AspNetCore.SignalR.Client
@using Gurux.DLMS.AMI.Shared.Enums
@using Gurux.DLMS.AMI.Client.Helpers
@using Gurux.DLMS.AMI.Module

@attribute [Authorize(Roles = "Admin, TemplateManager")]
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IGXNotifier Notifier
@implements IDisposable

<GXTable @ref="table"
         Context="value"
         ItemsProvider="@GetItems"
         SelectionMode="SelectionMode.Multiple"
         Filter="@Filter"
         ShowAllUsers="@Header"
         ShowRemoved="@Header"
         Columns="@Columns"
         CanEdit="@CanEdit"
         OnSearch="@Updated">
    <FilterContent>
        <th>
            <input class="form-control" placeholder="Filter by read time..."
                   type="datetime-local"
                   @onchange="@((ChangeEventArgs __e) => filter.Read = @StatusTile.ToDateTimeOffset(__e.Value))" />
        </th>
        <th>
            <input class="form-control" placeholder="Filter by value..."
                   type="text"
                   @onchange="@((ChangeEventArgs __e) => filter.Value = Convert.ToString(__e.Value))" />
        </th>
    </FilterContent>
    <MenuContent>
    </MenuContent>
    <HeaderContent>
        <Th>@Properties.Resources.Read</Th>
        <Th>@Properties.Resources.Values</Th>
    </HeaderContent>
    <ItemContent>
        @if (value.Read != null)
        {
            <td>@value.Read.Value.DateTime</td>
        }
        else
        {
            <td></td>
        }
        <td>@value.Value</td>
    </ItemContent>
</GXTable>
<br />
<Confirm @ref="ClearConfirmation"
         ConfirmationChanged="OnClearConfirmation"
         OkTitle="@Properties.Resources.Clear"
         AllowDelete="false"
         ConfirmationMessage="Are you sure you want to clear history? This action cannot be undone.">
</Confirm>
@code {

    [CascadingParameter]
    private AttributeTile? Parent { get; set; }


    [Parameter]
    public Guid? Id
    {
        get;
        set;
    }

    /// <summary>
    /// Amount of the history items shown on the view.
    /// </summary>
    [Parameter]
    public int Count { get; set; } = 0;

    /// <summary>
    /// Is filter shown.
    /// </summary>
    [Parameter]
    public bool Filter { get; set; } = true;

    /// <summary>
    /// Is header shown.
    /// </summary>
    [Parameter]
    public bool Header { get; set; } = true;

    /// <summary>
    /// Is edit allowed.
    /// </summary>
    [Parameter]
    public bool CanEdit { get; set; } = true;

    /// <summary>
    /// Available columns.
    /// </summary>
    [Parameter]
    public string[]? Columns { get; set; }

    /// <summary>
    /// Is title shown.
    /// </summary>
    [Parameter]
    public bool Title { get; set; } = true;

    internal int Total
    {
        get;
        private set;
    }


    private string? GetVersion(string? version)
    {
        if (version == null)
        {
            return Properties.Resources.CustomBuild;
        }
        return version;
    }

    private GXValue filter = new GXValue();
    //Verify that history is clear.
    protected ConfirmBase? ClearConfirmation;

    /// <summary>
    /// Reference to the table.
    /// </summary>
    private GXTable<GXValue>? table;

    /// <summary>
    /// Update table.
    /// </summary>
    /// <returns></returns>
    protected async Task Updated()
    {
        try
        {
            if (table != null)
            {
                Notifier?.ClearStatus();
                await table.RefreshDataAsync(true);
            }
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
    }

    protected override void OnInitialized()
    {
        try
        {
            if (Notifier == null)
            {
                throw new ArgumentException(Properties.Resources.InvalidNotifier);
            }
            Notifier.ClearStatus();
            Notifier.Clear();
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Clear, Icon = "oi oi-trash", OnClick = OnClear });
            Notifier.AddMenuItem(new GXMenuItem() { Text = Properties.Resources.Close, Icon = "oi oi-action-undo", OnClick = OnCancel });
            Notifier.UpdateButtons();
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
    }

    private async ValueTask<ItemsProviderResult<GXValue>> GetItems(GXItemsProviderRequest request)
    {
        try
        {
            //Don't clear status or error is lost.
            Notifier?.ProgressStart();
            List<object[]> rows = new();
            filter.Attribute = new GXAttribute() { Id = Id.Value };
            ListValues req = new ListValues() { Index = request.StartIndex, Count = request.Count, Filter = filter, Descending = true };
            var ret = await Http.PostAsJson<ListValuesResponse>("api/Value/List", req, request.CancellationToken);
            return new ItemsProviderResult<GXValue>(ret.Values, ret.Count);
        }
        catch (TaskCanceledException)
        {
            //Let the table component handle this.
            throw;
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
        return default;
    }

    /// <summary>
    /// Clear history.
    /// </summary>
    public void OnClear()
    {
        try
        {
            ClearConfirmation?.Show();
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
    }

    /// <summary>
    /// Clear history.
    /// </summary>
    public async Task OnClearConfirmation(ConfirmArgs args)
    {
        try
        {
            if (args.Confirm && Id != null)
            {
                ClearValue arg = new ClearValue()
                    {
                        Attributes = new GXAttribute[] { new GXAttribute() { Id = Id.Value } }
                    };
                await Http.PostAsJson<ClearValueResponse>("api/Value/Clear", arg);
                await Updated();
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
    }

    /// <summary>
    /// Cancel.
    /// </summary>
    private void OnCancel()
    {
        ClientHelpers.NavigateToLastPage(NavigationManager, Notifier);
    }

    public void Dispose()
    {
        Notifier.RemoveListener(this);
    }
}

